public class CompMatrix {
	private int n, m;
	private CompNumber[][] matrix;

	public CompMatrix(CompNumber[][] matrix) {
		this.matrix = matrix;
		this.n = matrix.length;
		this.m = matrix[0].length;
	}

	public boolean hasSameSize(CompMatrix matr) {
		return n == matr.n && m == matr.m;
	}

	@Override
	public String toString() {
		String s = "";
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				s += matrix[i][j] + " ";
			}
			s += "\n";
		}
		return s;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		if (this.getClass() == obj.getClass()) {
			CompMatrix matr = (CompMatrix) obj;
			if (matr.n == n && matr.m == m && matr.matrix.equals(matrix)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hash = 1;
		hash = hash * 17 + (int) m;
		hash = hash * 17 + (int) n;
		hash= hash*17 + matrix.hashCode();
		return hash;
	}

	public CompMatrix plus(CompMatrix matr) {
		if (!hasSameSize(matr)) {
			return null;
		}
		CompNumber[][] result = new CompNumber[n][m];

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				result[i][j] = matrix[i][j].plus(matr.matrix[i][j]);
			}
		}
		return new CompMatrix(result);
	}

	public CompMatrix minus(CompMatrix matr) {
		if (!hasSameSize(matr)) {
			return null;
		}
		CompNumber[][] result = new CompNumber[n][m];

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				result[i][j] = matrix[i][j].minus(matr.matrix[i][j]);
			}
		}
		return new CompMatrix(result);
	}

	public CompMatrix multiplyBy(CompMatrix matr) {
		if (m != matr.n) {
			return null;
		}
		CompNumber[][] result = new CompNumber[n][matr.m];

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < matr.m; j++) {
				result[i][j] = new CompNumber(0);

				for (int k = 0; k < m; k++) {
					result[i][j] = result[i][j].plus(matrix[i][k]
							.multiply(matr.matrix[k][j]));
				}
			}
		}
		return new CompMatrix(result);
	}
}